/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * tokyo.h
 * Copyright (C) Francesco Marcantoni 2006 <ramyel@gmail.com>
 * 
 * You may redistribute it and/or modify it under the terms of the
 * GNU General Public License, as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option)
 * any later version.
 * 
 * main.c is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with main.c.  If not, write to:
 * 	The Free Software Foundation, Inc.,
 * 	51 Franklin Street, Fifth Floor
 * 	Boston, MA  02110-1301, USA.
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>

#include <config.h>

#include <glib.h>

#include "log.h"


#ifdef ENABLE_NLS
#  include <libintl.h>
#  undef _
#  define _(String) dgettext (PACKAGE, String)
#  ifdef gettext_noop
#    define N_(String) gettext_noop (String)
#  else
#    define N_(String) (String)
#  endif
#else
#  define textdomain(String) (String)
#  define gettext(String) (String)
#  define dgettext(Domain,Message) (Message)
#  define dcgettext(Domain,Message,Type) (Message)
#  define bindtextdomain(Domain,Directory) (Domain)
#  define _(String) (String)
#  define N_(String) (String)
#endif

/********************
 Define
*/
#define NET_PORT 7001


/********************
 Macro
*/
#define LIST_DATA(struct, list)		((struct*)(list->data))
#define SFREE(x)	if(x) g_free(x);
#define RECREATE(result,type,number)                                    \
do                                                                      \
{                                                                       \
   if(!((result) = (type *)g_realloc((result), sizeof(type) * (number)))) \
   {                                                                    \
      tlog (P_ERROR, "RECREATE", _("Realloc failure @ %s:%d\n"), __FILE__, __LINE__); \
      abort();                                                          \
   }                                                                    \
} while(0)


/********************
 Definizioni di variabili globali.
*/
#define TOKYO_NAME_PROGRAM "Tokyo"
#define MSL 4096
#define MIL 1024

// Debug
gboolean tokyo_debug;
#define TOKYO_DEBUG tokyo_debug

// Errori
GQuark tokyo_quark_error;
#define TOKYO_ERROR tokyo_quark_error

typedef enum
{
	TOKYO_ERROR_DB_CHAR_LOAD_NO_MATCH,
} TokyoError;

// net.c
GList* descriptors; // Lista dei descrittori
gint maxdesc;
gint control_socket; // Descrittore del Socket
fd_set in_set; // Set of desc's for reading
fd_set out_set;  // Set of desc's for writing
fd_set exc_set; // Set of desc's with errors
gint newdesc; // New descriptor

/*
 Identificatori per il tipo di dato.
 Questa struttura identifica le chiavi
 di lettura per il Client.
 Ogni dato inviato deve essere preceduto da un tipo
 cosi' da permettere al Client di ricevere l'informazione
 corretta e di trattare i dati in modo opportuno.
*/
typedef enum
{
	NET_CTYPE_NORMAL, // Stringa
	NET_CTYPE_PROMPT, // Informazioni per il Prompt
	NET_CTYPE_MAX
} NetCType;

/*
 Stato della connessione
*/
typedef enum
{
	NET_CSTATE_NEW_DESC, // Appena connesso
	NET_CSTATE_PLAY, // In gioco
	NET_CSTATE_MAX
} NetCState;


/* char_send.c */
typedef enum
{
	SEND_STOP = -1, // Stop
	SEND_STRING, // Stringa
	SEND_NUMBER, // Numero
	SEND_CHAR, // Carattere
	SEND_MAX // Nullo
} SendType;

/********************
 Strutture
*/
typedef struct Character S_CHAR;
typedef struct Descriptor S_DESCRIPTOR;

/* Character.c */
struct Character
{
	S_DESCRIPTOR *desc;
	gchar *name;

	/* Statistiche base */
	gint str;
	gint wis;
	gint inte;
	gint con;
	gint cha;
	gint dex;

	/* Statistiche modificate */
	gint cur_str;
	gint cur_wis;
	gint cur_inte;
	gint cur_con;
	gint cur_cha;
	gint cur_dex;
};

/* net.c */
struct Descriptor
{
	gint descriptor;
	gchar inbuf[MSL];
	gint port;
	gchar *host;
	gboolean fcommand;
	gint outtop;
	gchar *outbuf;
	gint outsize;
	S_CHAR *character;

	NetCState connect_state;
};


/********************
 Funzioni
*/
/* character.c */
void		char_free ( S_CHAR* ch );
void		char_init ( S_CHAR* ch );

/* char_send.c */
void		char_d_send ( S_DESCRIPTOR *d, NetCType type, ... );
void		char_send ( S_CHAR *ch, NetCType type, ... );
void		char_send_prompt ( S_CHAR *ch );

/* init.c */
gboolean	init_all ( gboolean debug );

/* net.c */
gint		net_init_socket ( gint port );
gboolean	net_main ();
void		net_accept_new ( gint ctrl );
void		net_loop ( void );
void		net_close_socket ( S_DESCRIPTOR *dclose, gboolean force );
void		net_new_descriptor ( gint new_desc );
gboolean	net_check_bad_desc ( gint desc );
gboolean	net_read_from_descriptor ( S_DESCRIPTOR *d );
gboolean	net_write_to_descriptor ( S_DESCRIPTOR *d, gchar *txt, gint length );
void		net_write_to_buffer ( S_DESCRIPTOR * d, const gchar *txt, guint length );
gboolean	net_flush_buffer ( S_DESCRIPTOR * d, gboolean fPrompt );

/* db_char.c */
S_CHAR		*db_char_load ( const gchar *filename );
gboolean	db_char_save ( const gchar *filename, S_CHAR *ch );
